package com.qf.aspect;

import com.alibaba.fastjson.JSONObject;
import com.qf.pojo.User;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.List;

/**
 * 自定义的切面实现类
 *    MethodBeforeAdvice：前置
 *    1、implements MethodBeforeAdvice, AfterReturningAdvice,...... ：配置式
 *    2、注解式开发
 *      前置
 *      后置
 *      异常
 *      环绕
 *
 *      语义区别：
 *      @Component //实例化 :  POJO、切面、VO、DTO
 *      @Service   //实例化 :  只给它使用UserServiceImpl
 *      @Repository//实例化 : Dao层使用    Mybatis：自带扫描包Mapper接口、没有Mapper的实现类
 *      @Controller//实例化： Servlet层使用的
 *
 *
 *      切面实现类
 *
 * @author lixu
 */
@Component //实例化
@Aspect  //切面注解
public class MyAspect  {

    //将表达式向上抽取
    @Pointcut(value = "execution(* com.qf.service.UserServiceImpl.queryUser(..))")
    public void pointCut(){};

    /**
     * 前置 通知 注解  @Before()
     */
    @Before(value = "pointCut()")
    public void beforeAdvice(JoinPoint joinPoint){//切入点
        Object[] args = joinPoint.getArgs();
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        Class returnType = methodSignature.getReturnType();
        System.out.println("事务管理");
        System.out.println("日志管理");
    }

    /**
     * 后置  ,returning = "r": 只能后置有方法执行后的返回值
     *
     *   后置与异常通知  二者只能走一个 不能同时走
     */
    @AfterReturning(value = "pointCut()",returning = "r")
    public void afterAdvice(JoinPoint joinPoint,Object r){//切入点
        Object[] args = joinPoint.getArgs();
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        Class returnType = methodSignature.getReturnType();

        List<User> rList = (List<User>) r;
        for (User user : rList) {
            System.out.println(user);
        }

        System.out.println("快红霉素注射液");
        System.out.println("结束");
    }

    /**
     * 异常
     */
    @AfterThrowing(value = "pointCut()",throwing = "e")
    public void throwAdvice(JoinPoint joinPoint,Exception e){//切入点
        System.out.println("是什么异常:" + e.getMessage());
    }
    /**
     * 环绕
     */
    @Around(value = "pointCut()")
    public Object aroundAdvice(ProceedingJoinPoint pjp){
        System.out.println("方法之前进入环绕AroundAdvice");

        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        //方法的返回值类型
        Class returnType = methodSignature.getReturnType();

        Object[] args = pjp.getArgs();
        // int.class  User.class
        //执行核心代码
        try {
            Object result = pjp.proceed(args);
            System.out.println("==后置代码");
            //返回值
            return result;
        } catch (Throwable throwable) {
            //throwable.printStackTrace();
            System.out.println("AroundAdvice是什么异常：" + throwable.getMessage());
        }
        return null;
    }



}
